#ifndef MD5_H
#define MD5_H

#include <cstdint> 
#include <cstring>  
#include <string>
#include <sstream>   
#include <algorithm>  

// 初始化MD5上下文
class MD5 {
public:
    MD5() {
        m_state[0] = 0x67452301;
        m_state[1] = 0xEFCDAB89;
        m_state[2] = 0x98BADCFE;
        m_state[3] = 0x10325476;
        m_bit_count[0] = 0;
        m_bit_count[1] = 0;
        m_buffer_index = 0;
    }

    // 处理输入数据
    void update(const uint8_t* data, size_t len) {
        uint32_t old_count = m_bit_count[0];
        m_bit_count[0] += static_cast<uint32_t>(len << 3);
        if (m_bit_count[0] < old_count) m_bit_count[1]++;
        m_bit_count[1] += static_cast<uint32_t>(len >> 29);

        size_t offset = 0;
        while (offset < len) {
            size_t copy_len = std::min<size_t>(
                len - offset,
                64 - m_buffer_index  
            );
            memcpy(m_buffer + m_buffer_index, data + offset, copy_len);
            m_buffer_index += copy_len;
            offset += copy_len;

            if (m_buffer_index == 64) {
                transform(m_buffer);
                m_buffer_index = 0;
            }
        }
    }

    // 生成16进制字符串
    std::string hexdigest() {
        finalize();
        std::stringstream ss;
        for (int i = 0; i < 16; ++i) {
            uint8_t byte = reinterpret_cast<uint8_t*>(m_state)[i];
            ss << std::hex << (byte >> 4) << (byte & 0xF);
        }
        return ss.str();
    }

private:
    uint32_t m_state[4];     // MD5状态寄存器 (A/B/C/D)
    uint8_t m_buffer[64];    // 输入缓冲区（64字节块）
    uint32_t m_bit_count[2]; // 总位数（低32位 + 高32位）
    uint32_t m_buffer_index; // 缓冲区当前索引（0-63）

// MD5核心变换函数
inline void transform(const uint8_t block[64])
{
    uint32_t a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3];
    uint32_t x[16];
    decode(x, block, 64);  // 将64字节块解码为16个32位整数（小端序）

    // 定义MD5四轮运算的宏
    #define FF(a, b, c, d, x, s, ac) { \
        a += ((b & c) | (~b & d)) + x + ac; \
        a = (a << s) | (a >> (32 - s)); \
        a += b; \
    }
    #define GG(a, b, c, d, x, s, ac) { \
        a += ((b & d) | (c & ~d)) + x + ac; \
        a = (a << s) | (a >> (32 - s)); \
        a += b; \
    }
    #define HH(a, b, c, d, x, s, ac) { \
        a += (b ^ c ^ d) + x + ac; \
        a = (a << s) | (a >> (32 - s)); \
        a += b; \
    }
    #define II(a, b, c, d, x, s, ac) { \
        a += (c ^ (b | ~d)) + x + ac; \
        a = (a << s) | (a >> (32 - s)); \
        a += b; \
    }

    // ====================== 第一轮（16步） ======================
    FF(a, b, c, d, x[0],  7, 0xD76AA478)
    FF(d, a, b, c, x[1], 12, 0xE8C7B756)
    FF(c, d, a, b, x[2], 17, 0x242070DB)
    FF(b, c, d, a, x[3], 22, 0xC1BDCEEE)
    FF(a, b, c, d, x[4],  7, 0xF57C0FAF)
    FF(d, a, b, c, x[5], 12, 0x4787C62A)
    FF(c, d, a, b, x[6], 17, 0xA8304613)
    FF(b, c, d, a, x[7], 22, 0xFD469501)
    FF(a, b, c, d, x[8],  7, 0x698098D8)
    FF(d, a, b, c, x[9], 12, 0x8B44F7AF)
    FF(c, d, a, b, x[10],17, 0xFFFF5BB1)
    FF(b, c, d, a, x[11],22, 0x895CD7BE)
    FF(a, b, c, d, x[12], 7, 0x6B901122)
    FF(d, a, b, c, x[13],12, 0xFD987193)
    FF(c, d, a, b, x[14],17, 0xA679438E)
    FF(b, c, d, a, x[15],22, 0x49B40821)

    // ====================== 第二轮（16步） ======================
    GG(a, b, c, d, x[1],  5, 0xF61E2562)
    GG(d, a, b, c, x[6],  9, 0xC040B340)
    GG(c, d, a, b, x[11],14, 0x265E5A51)
    GG(b, c, d, a, x[0], 20, 0xE9B6C7AA)
    GG(a, b, c, d, x[5],  5, 0xD62F105D)
    GG(d, a, b, c, x[10], 9, 0x02441453)
    GG(c, d, a, b, x[15],14, 0xD8A1E681)
    GG(b, c, d, a, x[4], 20, 0xE7D3FBC8)
    GG(a, b, c, d, x[9],  5, 0x21E1CDE6)
    GG(d, a, b, c, x[14], 9, 0xC33707D6)
    GG(c, d, a, b, x[3], 14, 0xF4D50D87)
    GG(b, c, d, a, x[8], 20, 0x455A14ED)
    GG(a, b, c, d, x[13], 5, 0xA9E3E905)
    GG(d, a, b, c, x[2],  9, 0xFCEFA3F8)
    GG(c, d, a, b, x[7], 14, 0x676F02D9)
    GG(b, c, d, a, x[12],20, 0x8D2A4C8A)

    // ====================== 第三轮（16步） ======================
    HH(a, b, c, d, x[5],  4, 0xFFFA3942)
    HH(d, a, b, c, x[8], 11, 0x8771F681)
    HH(c, d, a, b, x[11],16, 0x6D9D6122)
    HH(b, c, d, a, x[14],23, 0xFDE5380C)
    HH(a, b, c, d, x[1],  4, 0xA4BEEA44)
    HH(d, a, b, c, x[4], 11, 0x4BDECFA9)
    HH(c, d, a, b, x[7], 16, 0xF6BB4B60)
    HH(b, c, d, a, x[10],23, 0xBEBFBC70)
    HH(a, b, c, d, x[13], 4, 0x289B7EC6)
    HH(d, a, b, c, x[0], 11, 0xEAA127FA)
    HH(c, d, a, b, x[3], 16, 0xD4EF3085)
    HH(b, c, d, a, x[6], 23, 0x04881D05)
    HH(a, b, c, d, x[9],  4, 0xD9D4D039)
    HH(d, a, b, c, x[12],11, 0xE6DB99E5)
    HH(c, d, a, b, x[15],16, 0x1FA27CF8)
    HH(b, c, d, a, x[2], 23, 0xC4AC5665)

    // ====================== 第四轮（16步） ======================
    II(a, b, c, d, x[0],  6, 0xF4292244)
    II(d, a, b, c, x[7], 10, 0x432AFF97)
    II(c, d, a, b, x[14],15, 0xAB9423A7)
    II(b, c, d, a, x[5], 21, 0xFC93A039)
    II(a, b, c, d, x[12], 6, 0x655B59C3)
    II(d, a, b, c, x[3], 10, 0x8F0CCC92)
    II(c, d, a, b, x[10],15, 0xFFEFF47D)
    II(b, c, d, a, x[1], 21, 0x85845DD1)
    II(a, b, c, d, x[8],  6, 0x6FA87E4F)
    II(d, a, b, c, x[15],10, 0xFE2CE6E0)
    II(c, d, a, b, x[6], 15, 0xA3014314)
    II(b, c, d, a, x[13],21, 0x4E0811A1)
    II(a, b, c, d, x[4],  6, 0xF7537E82)
    II(d, a, b, c, x[11],10, 0xBD3AF235)
    II(c, d, a, b, x[2], 15, 0x2AD7D2BB)
    II(b, c, d, a, x[9], 21, 0xEB86D391)

    // 更新状态寄存器
    m_state[0] += a;
    m_state[1] += b;
    m_state[2] += c;
    m_state[3] += d;

    // 清空临时数据
    memset(x, 0, sizeof(x));
}
    // 生成最终摘要
    inline void finalize() {
        static const uint8_t padding[64] = {0x80};
        uint8_t bits[8];
        memcpy(bits, &m_bit_count[0], 4);
        memcpy(bits + 4, &m_bit_count[1], 4);

        size_t pad_len = (m_buffer_index < 56) ? 56 - m_buffer_index : 120 - m_buffer_index;
        update(padding, pad_len);
        update(bits, 8);
    }
    // 将字节流解码为32位整数（小端序）
    static inline void decode(uint32_t* output, const uint8_t* input, size_t len) {
        for (size_t i = 0, j = 0; j < len; i++, j += 4) {
            output[i] = (input[j]) | (input[j+1] << 8) | (input[j+2] << 16) | (input[j+3] << 24);
        }
    }
};

#endif // MD5_H